package main

// Working from the description of shell language at:
// http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html

// Parser settings. These are mostly just for performance tuning.
const (
	INPUT_BUF_SIZE = 1024
	CMD_BUF_SIZE = 128
)

func ParseAll(buf string) ([]Command, error) {
	rawC, cmdC, errC := Parser() // TODO handle errors
	cmdsC := make(chan []Command, 1)
	go func() {
		defer close(rawC)
		for _, r := range buf {
			rawC <- r
		}
	}()
	go func() {
		var cs []Command
		for c := range cmdC {
			cs = append(cs, c)
		}
		cmdsC <- cs
		close(cmdsC)
	}()
	select {
	case err, ok := <-errC:
		if ok {
			return nil, err
		}
	case cs := <-cmdsC:
		return cs, nil
	}
	return (<-cmdsC), nil
}

func Parser() (chan<- rune, <-chan Command, <-chan error) {
	rawC := make(chan rune, INPUT_BUF_SIZE)
	cmdC := make(chan Command, CMD_BUF_SIZE)
	errC := make(chan error)
	go doParse(rawC, cmdC, errC)
	return rawC, cmdC, errC
}

type parserState int

const (
	READY parserState = iota
)

func doParse(rawC <-chan rune, cmdC chan<- Command, errC chan<- error) {

	close(cmdC)
	close(errC)
}
